home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / news / transport / cnews / msgidd / msgidd.shar / msgid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-26  |  4.7 KB  |  218 lines

  1. /* msgid -- message ID test
  2.  * vix 13feb91 [negative caching]
  3.  * vix 24may90 [written]
  4.  *
  5.  * with mods ken@sdd.hp.com 01jul90
  6.  *
  7.  * $Header: msgid.c,v 1.6 91/08/17 12:04:11 vixie Locked $
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <sys/types.h>
  13. #include <sys/time.h>
  14. #ifdef hpux
  15. #include <sys/param.h>
  16. #include <libBSD.h>
  17. #endif
  18. #include <sys/socket.h>
  19. #include <sys/un.h>
  20. #include <syslog.h>
  21. #define NEEDMSGS
  22. #include "msgid.h"
  23. #include "../common/conf.h"
  24.  
  25. #ifdef MSGID
  26.  
  27. #ifdef WANT_MAIN
  28. char hostname[BUFSIZ];
  29. #else
  30. extern char hostname[];
  31. #endif
  32.  
  33. #define SERVERTIMEOUT    30
  34.  
  35. static int s = -1;
  36. static int read_answer();
  37.  
  38. /*
  39.  * Protocol:
  40.  *    Return value as used here is from the server to us.  Note that this
  41.  *    may not be the same as the return value from msgid().
  42.  *
  43.  *    3 message types:
  44.  *        MCANCEL: Delete an id from the holding queues.  Return value
  45.  *                 is non-zero for failure.
  46.  *        MADD:    Check for dup and add as needed.  Return value is 
  47.  *                 non-zero for dup.
  48.  *        MHOST:   Used to inform the server who is on the other end of this 
  49.  *                 nntpd.  Return value is non-zero for failure.  Used only
  50.  *                 in msgid_init().
  51.  */
  52.  
  53.  
  54. /* 
  55.  * returns: 0 for ok, 1 for failure
  56.  */
  57. msgid_init()
  58. {
  59.     char buf[300];
  60.     struct sockaddr_un n;
  61.     static dead_server_count = 0;
  62.  
  63.     s = socket(PF_UNIX, SOCK_STREAM, 0);
  64.     if (s < 0) {
  65.     syslog(LOG_ERR, "msgid: can't get socket: %m");
  66.     return(1);
  67.     }
  68.  
  69.     n.sun_family = AF_UNIX;
  70.     (void) strcpy(n.sun_path, SOCKNAME);
  71.  
  72.     if (0 > connect(s, &n, strlen(n.sun_path) + sizeof n.sun_family)) {
  73.     close(s);
  74.     s = -1;
  75.     /* only syslog every 128 messages, so that dead msgidd doesn't
  76.      * lead to multi-megabyte syslog files (vix, 13feb91)
  77.      */
  78.     if (!(dead_server_count++ % 128)) {
  79.         syslog(LOG_ERR, "msgid: connect to %s: %m", SOCKNAME);
  80.     }
  81.     return(1);
  82.     }
  83.  
  84.     (void) strcpy(buf, msgs[MHOST]);
  85.     (void) strcat(buf, hostname);
  86.     if (write(s, buf, strlen(buf)) < 0) {
  87.     close(s);
  88.     s = -1;
  89.     syslog(LOG_ERR, "msgid: host message write: %m", SOCKNAME);
  90.     return(1);
  91.     }
  92.  
  93.     return(read_answer());
  94. }
  95.  
  96.  
  97. /* 
  98.  * returns: nonzero = duplicate, return value doesn't mean much for the
  99.  *          MADD or MOLD messages
  100.  */
  101. int
  102. msgid(id, mtype)
  103.     char *id;
  104.     int mtype;
  105. {
  106.     char *cp, buf[256], *rindex();
  107.  
  108.     if (s == -1 && msgid_init())
  109.     return(0);
  110.  
  111.     /*
  112.      * We need to do this just because gethistent does it
  113.      * "in place" so add vs old gets fried ...
  114.      *
  115.      * If running Bnews, converts "id" to lower case.
  116.      * If running Cnews, converts "id" per rfc822.
  117.      */
  118. #ifdef CNEWS
  119.     cp = rindex(id, '@');        /* look for @ in message id */
  120.     if (cp != NULL) {
  121.     for(; *cp != '\0'; ++cp)
  122. #else
  123.     {
  124.     for (cp = msg_id; *cp != '\0'; ++cp)
  125. #endif
  126.         if (isupper(*cp))
  127.         *cp = tolower(*cp);
  128.     }
  129.     (void) strcpy(buf, msgs[mtype]);
  130.     (void) strcat(buf, id);
  131.     if (0 > write(s, buf, strlen(buf))) {
  132.     syslog(LOG_ERR, "msgid: write: %m");
  133.     close(s);
  134.     s = -1;
  135.     return(0);
  136.     }
  137.     return(read_answer()); 
  138. }
  139.  
  140.  
  141. static int
  142. read_answer()
  143. {
  144.     unsigned char c;
  145.     fd_set readfds;
  146.     struct timeval to;
  147.     int i;
  148.  
  149.     FD_ZERO(&readfds);
  150.     FD_SET(s, &readfds);
  151.     to.tv_sec = SERVERTIMEOUT;
  152.     to.tv_usec = 0;
  153.     if ((i = select(s+1, &readfds, NULL, NULL, &to)) < 0) {
  154.     syslog(LOG_ERR, "msgid: select: %m");
  155.     goto bad;
  156.     }
  157.     if (i == 0 || FD_ISSET(s, &readfds) == 0 || (i = read(s, &c, 1)) == 0) {
  158.     syslog(LOG_ERR, "msgid: read timeout");
  159.     goto bad;
  160.     }
  161.     if (i < 0) {
  162.     syslog(LOG_ERR, "msgid: read: %m");
  163.     goto bad;
  164.     }
  165.     if (c)
  166.     return(1);
  167.     return(0);
  168. bad:
  169.     close(s);
  170.     s = -1;
  171.     return 0;
  172. }
  173.  
  174. #ifdef WANT_MAIN
  175. main(argc, argv)
  176.     int argc;
  177.     char *argv[];
  178. {
  179.     register int n;
  180.     char buf[BUFSIZ], cmd[20], id[BUFSIZ];
  181.  
  182.     if (gethostname(hostname, BUFSIZ)) {
  183.     perror("hostname");
  184.     exit(1);
  185.     }
  186.     (void) printf("host: %s\n", hostname);
  187.  
  188.     if (argc != 1) {
  189.     (void) fprintf(stderr, "usage: %s\n", argv[0]);
  190.     exit(1);
  191.     }
  192.  
  193. #ifdef LOG_DAEMON
  194.     openlog("msgid-test", LOG_PID, LOG_DAEMON);
  195. #else
  196.     openlog("msgid-test", LOG_PID);
  197. #endif
  198.  
  199.     while (fputs("cmd msgid: ", stdout), fflush(stdout), fgets(buf, BUFSIZ, stdin))
  200.     if ((n = sscanf(buf, "%[^ \t]%*[ \t]%[^\n]", cmd, id)) == 2) {
  201.         if (strcmp(cmd, "cancel") == 0)
  202.         (void) printf("%s\n", (msgid(id, MCANCEL) ? "failed" : "ok"));
  203.         else if (strcmp(cmd, "add") == 0)
  204.         (void) printf("%d\n", msgid(id, MADD));
  205.         /* 
  206.         (void) printf("%sduplicate\n", 
  207.                   (msgid(id, MADD) ? "" : "not a "));
  208.         */
  209.         else if (strcmp(cmd, "old") == 0)
  210.         (void) printf("%s\n", (msgid(id, MOLD) ? "failed" : "ok"));
  211.         else
  212.         (void) printf("possible cmds are cancel, add, and old\n");
  213.     } else
  214.         (void) printf("[%d] possible cmds are cancel, add, and old\n", n);
  215. }
  216. #endif
  217. #endif MSGID
  218.